#ifndef __NP__
#define __NP__

#include <iostream>
#include <string>

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <string>

#include "log.hpp"

using namespace std;

enum {
    CREATE_ERR = 1,
    OPEN_ERR = 2,
    CLOSE_ERR = 3,
    READ_ERR = 4,
    WRITE_ERR = 5,
    DELETE_ERR = 6
};

#define BUFFSIZE 1024

#define NPIPE_NAME "./myfifo"
#define DEFAULT_MODE 0664

// 读端类
class RDNamedPipe {
public:
    RDNamedPipe() {
        int fd = open(NPIPE_NAME, O_RDONLY);
        if(fd < 0) {
            _log(FATAL, "open file error in O_RDONLY, errno: %d message string: %s", errno, strerror(errno));
            exit(OPEN_ERR);
        }
        _fd = fd;
    }
    // 从管道读数据
    ssize_t Read(string* const str) const {
        char buff[BUFFSIZE]{};
        ssize_t n = read(_fd, buff, sizeof buff);
        if(n > 0) {
            buff[n] = '\0';
            *str = buff;
        }
        return n;
    }
    ~RDNamedPipe() {
        if(unlink(NPIPE_NAME) == -1) {
            _log(FATAL, "unlink file error, errno: %d message string: %s", errno, strerror(errno));
            exit(DELETE_ERR);
        }
        close(_fd);
    }
private:
    int _fd; 
    logger _log;
};

//写端类
class WDNamedPipe {
public:
    WDNamedPipe() {
        int fd = open(NPIPE_NAME, O_WRONLY | O_TRUNC);
        if(fd < 0) {
            _log(FATAL, "open file error in O_WRONLY | O_TRUNC, errno: %d message string: %s", errno, strerror(errno));
            exit(OPEN_ERR);
        }
        _fd = fd;
    }
    // 向管道写入数据
    ssize_t Write(const string& str) const {
        return write(_fd, str.c_str(), str.size());
    }
    ~WDNamedPipe() {
        if(unlink(NPIPE_NAME) == -1) {
            _log(FATAL, "unlink file error, errno: %d message string: %s", errno, strerror(errno));
            exit(DELETE_ERR);
        }
        close(_fd);
    }
private:
    int _fd; 
    logger _log;
};

#endif